package services

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// VenvService 提供虚拟环境管理功能
type VenvService struct {
	venvDir string
}

// NewVenvService 创建一个新的虚拟环境服务实例
func NewVenvService(venvDir string) *VenvService {
	return &VenvService{
		venvDir: venvDir,
	}
}

// CreateVenv 创建新的虚拟环境
func (s *VenvService) CreateVenv(name string, pythonVersion string) error {
	venvPath := filepath.Join(s.venvDir, name)

	// 检查环境是否已存在
	if _, err := os.Stat(venvPath); err == nil {
		return fmt.Errorf("virtual environment '%s' already exists", name)
	}

	// 构建 Python 可执行文件名
	pythonExe := fmt.Sprintf("python%s", pythonVersion)
	if strings.HasPrefix(pythonVersion, "3") {
		pythonExe = fmt.Sprintf("python%s", pythonVersion)
	}
	//直接使用默认的python版本去创建
	pythonExe = "python"
	// 创建虚拟环境
	cmd := exec.Command(pythonExe, "-m", "venv", venvPath)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to create virtual environment: %v", err)
	}

	return nil
}

// DeleteVenv 删除虚拟环境
func (s *VenvService) DeleteVenv(name string) error {
	venvPath := filepath.Join(s.venvDir, name)

	// 检查环境是否存在
	if _, err := os.Stat(venvPath); os.IsNotExist(err) {
		return fmt.Errorf("virtual environment '%s' does not exist", name)
	}

	// 删除虚拟环境目录
	if err := os.RemoveAll(venvPath); err != nil {
		return fmt.Errorf("failed to delete virtual environment: %v", err)
	}

	return nil
}

// InstallPackage 在指定的虚拟环境中安装包
func (s *VenvService) InstallPackage(venvName string, packageName string) error {
	venvPath := filepath.Join(s.venvDir, venvName)
	pipPath := filepath.Join(venvPath, "Scripts", "pip.exe")
	if os.PathSeparator != '\\' { // 非 Windows
		pipPath = filepath.Join(venvPath, "bin", "pip")
	}

	// 检查 pip 可执行文件是否存在
	if _, err := os.Stat(pipPath); os.IsNotExist(err) {
		return fmt.Errorf("pip executable not found in virtual environment: %v", err)
	}

	cmd := exec.Command(pipPath, "install", packageName)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to install package: %v, output: %s", err, string(output))
	}

	return nil
}

// UninstallPackage 从指定的虚拟环境中卸载包
func (s *VenvService) UninstallPackage(venvName string, packageName string) error {
	venvPath := filepath.Join(s.venvDir, venvName)
	pipPath := filepath.Join(venvPath, "Scripts", "pip.exe")
	if os.PathSeparator != '\\' { // 非 Windows
		pipPath = filepath.Join(venvPath, "bin", "pip")
	}

	// 检查 pip 可执行文件是否存在
	if _, err := os.Stat(pipPath); os.IsNotExist(err) {
		return fmt.Errorf("pip executable not found in virtual environment: %v", err)
	}

	cmd := exec.Command(pipPath, "uninstall", "-y", packageName)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to uninstall package: %v, output: %s", err, string(output))
	}

	return nil
}

// ListPackages 列出虚拟环境中已安装的包
func (s *VenvService) ListPackages(venvName string) ([]Package, error) {
	venvPath := filepath.Join(s.venvDir, venvName)
	pipPath := filepath.Join(venvPath, "Scripts", "pip.exe")
	if os.PathSeparator != '\\' { // 非 Windows
		pipPath = filepath.Join(venvPath, "bin", "pip")
	}

	// 检查 pip 可执行文件是否存在
	if _, err := os.Stat(pipPath); os.IsNotExist(err) {
		return nil, fmt.Errorf("pip executable not found in virtual environment: %v", err)
	}

	cmd := exec.Command(pipPath, "list", "--format=json")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to list packages: %v, output: %s", err, string(output))
	}

	// 从输出中提取 JSON 部分
	outputStr := string(output)
	startIdx := strings.Index(outputStr, "[")
	endIdx := strings.Index(outputStr, "]")

	if startIdx == -1 || endIdx == -1 {
		return nil, fmt.Errorf("invalid JSON output format: %s", outputStr)
	}

	jsonStr := outputStr[startIdx : endIdx+1]
	var packages []Package
	if err := json.Unmarshal([]byte(jsonStr), &packages); err != nil {
		return nil, fmt.Errorf("failed to parse package list: %v, json: %s", err, jsonStr)
	}

	return packages, nil
}

// GetVenvInfo 获取虚拟环境信息
func (s *VenvService) GetVenvInfo(name string) (*VenvInfo, error) {
	venvPath := filepath.Join(s.venvDir, name)

	// 检查环境是否存在
	if _, err := os.Stat(venvPath); os.IsNotExist(err) {
		return nil, fmt.Errorf("virtual environment '%s' does not exist", name)
	}

	// 获取 Python 版本
	pythonPath := filepath.Join(venvPath, "Scripts", "python.exe")
	if os.PathSeparator != '\\' { // 非 Windows
		pythonPath = filepath.Join(venvPath, "bin", "python")
	}

	// 检查 Python 可执行文件是否存在
	if _, err := os.Stat(pythonPath); os.IsNotExist(err) {
		return nil, fmt.Errorf("python executable not found in virtual environment: %v", err)
	}

	cmd := exec.Command(pythonPath, "--version")
	output, err := cmd.CombinedOutput() // 使用 CombinedOutput 来获取更多错误信息
	if err != nil {
		return nil, fmt.Errorf("failed to get Python version: %v, output: %s", err, string(output))
	}

	version := strings.TrimSpace(strings.TrimPrefix(string(output), "Python "))

	// 获取已安装的包数量
	pipPath := filepath.Join(venvPath, "Scripts", "pip.exe")
	if os.PathSeparator != '\\' { // 非 Windows
		pipPath = filepath.Join(venvPath, "bin", "pip")
	}

	// 检查 pip 可执行文件是否存在
	if _, err := os.Stat(pipPath); os.IsNotExist(err) {
		return nil, fmt.Errorf("pip executable not found in virtual environment: %v", err)
	}

	cmd = exec.Command(pipPath, "list", "--format=json")
	output, err = cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to list packages: %v, output: %s", err, string(output))
	}

	// 从输出中提取 JSON 部分
	outputStr := string(output)
	startIdx := strings.Index(outputStr, "[")
	endIdx := strings.Index(outputStr, "]")

	if startIdx == -1 || endIdx == -1 {
		return nil, fmt.Errorf("invalid JSON output format: %s", outputStr)
	}

	jsonStr := outputStr[startIdx : endIdx+1]
	var packages []Package
	if err := json.Unmarshal([]byte(jsonStr), &packages); err != nil {
		return nil, fmt.Errorf("failed to parse package list: %v, json: %s", err, jsonStr)
	}

	return &VenvInfo{
		Name:         name,
		Version:      version,
		PackageCount: len(packages),
		Path:         venvPath,
	}, nil
}

// ListVenvs 列出所有虚拟环境
func (s *VenvService) ListVenvs() ([]VenvInfo, error) {
	entries, err := os.ReadDir(s.venvDir)
	if err != nil {
		return nil, fmt.Errorf("failed to read venv directory: %v", err)
	}

	var venvs []VenvInfo
	for _, entry := range entries {
		if entry.IsDir() {
			info, err := s.GetVenvInfo(entry.Name())
			if err != nil {
				continue // 跳过无效的虚拟环境
			}
			venvs = append(venvs, *info)
		}
	}

	return venvs, nil
}

// Package 表示一个 Python 包
type Package struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

// VenvInfo 虚拟环境信息
type VenvInfo struct {
	Name         string `json:"name"`
	Version      string `json:"version"`
	PackageCount int    `json:"package_count"`
	Path         string `json:"path"`
}
